﻿using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;



namespace Basic4Net.Controls
{
	/*
	 * 样式：Class：BNPagerTextbox		//输入页数的输入框
	 * 样式：Class：BNPagerButtonGo		//跳转按钮“Go”
	 * 样式：Class：BNPagerTd			//用户区和控件区的Td
	 * 样式：Class：BNPagerButton		//“第一页”、“前一页”、“后一页”、“最后一页”
	 * 样式：Class：BNPagerLink			//“第一页”、“前一页”、“后一页”、“最后一页”
	 * 样式：Class：BNPagerIndexLink		//索引样式
	 */

	[DefaultProperty("PageSize")]
	[DefaultEvent("PageChanged")]
	[ParseChildren(false)]
	[PersistChildren(false)]
	[Description("Pager Control")]
	[Designer(typeof(PagerDesigner))]
	[ToolboxData("<{0}:BNPager runat=server></{0}:BNPager>")]
	public class BNPager : Panel, INamingContainer, IPostBackEventHandler, IPostBackDataHandler
	{
		private string inputPageIndex;
		//private string inputPageSize;

		/// <summary>
		/// 数据总数量
		/// </summary>
		[Browsable(false),
		Description("数据总数量"),
		Category("Data"),
		DefaultValue(0)]
		public int RecordCount
		{
			get
			{
				object obj = ViewState["RecordCount"];
				return (obj == null) ? 0 : (int)obj;
			}
			set { ViewState["RecordCount"] = value; }
		}

		#region 分页
		/// <summary>
		/// 当前页的索引
		/// </summary>
		/// <remarks>使用此属性来确定在 BNPager 控件中当前显示的页，当前显示的页的数字索引将以红色字体加粗显示。此属性还用于以编程的方式控制所显示的页。
		/// <p>　<b>注意：</b>不同于DataGrid控件的PageIndex，BNPager的PageIndex属性是从1开始的。</p>
		/// </remarks>
		[ReadOnly(true),
		Browsable(false),
		Description("当前页的索引"),
		Category("分页"),
		DefaultValue(1),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int PageIndex
		{
			get
			{
				if (ViewState["PageIndex"] == null)
					ViewState["PageIndex"] = 1;
				if ((int)ViewState["PageIndex"] > PageCount && PageCount > 0)
					ViewState["PageIndex"] = PageCount;
				return (int)ViewState["PageIndex"];
			}
			set
			{
				ViewState["PageIndex"] = value < 1 ? 1 : value;
			}
		}

		/// <summary>
		/// 分页控件在一页中显示的记录数
		/// </summary>
		[Browsable(true),
		Description("分页控件在一页中显示的记录数"),
		Category("分页"),
		DefaultValue(15)]
		public int PageSize
		{
			get
			{
				object obj = ViewState["PageSize"];
				return (obj == null) ? 15 : (int)obj;
			}
			set
			{
				ViewState["PageSize"] = value;
			}
		}

		/// <summary>
		/// 总页数
		/// </summary>
		[Browsable(false),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int PageCount
		{
			get { return (int)Math.Ceiling((double)RecordCount / (double)PageSize); }
		}
		#endregion

		#region 显示文本
		/// <summary>
		/// “第一页”按钮的文本
		/// </summary>
		[Browsable(true),
		Description("“第一页”按钮的文本"),
		Category("导航文本"),
        DefaultValue("首页")]
		public string FirstPageText
		{
			get
			{
				object obj = ViewState["FirstPageText"];
				return (obj == null) ? "首页" : (string)obj;
			}
			set { ViewState["FirstPageText"] = value; }
		}

		/// <summary>
		/// “上一页”按钮的文本
		/// </summary>
		[Browsable(true),
		Description("“上一页”按钮的文本"),
		Category("导航文本"),
        DefaultValue("上一页")]
		public string PreviousPageText
		{
			get
			{
				object obj = ViewState["PreviousPageText"];
				return (obj == null) ? "上一页" : (string)obj;
			}
			set { ViewState["PreviousPageText"] = value; }
		}

		/// <summary>
		/// “下一页”按钮的文本
		/// </summary>
		[Browsable(true),
		Description("“下一页”按钮的文本"),
		Category("导航文本"),
        DefaultValue("下一页")]
		public string NextPageText
		{
			get
			{
				object obj = ViewState["NextPageText"];
                return (obj == null) ? "下一页" : (string)obj;
			}
			set { ViewState["NextPageText"] = value; }
		}

		/// <summary>
		/// “最后一页”按钮的文本
		/// </summary>
		[Browsable(true),
		Description("“最后一页”按钮的文本"),
		Category("导航文本"),
		DefaultValue("末页")]
		public string LastPageText
		{
			get
			{
				object obj = ViewState["LastPageText"];
                return (obj == null) ? "末页" : (string)obj;
			}
			set { ViewState["LastPageText"] = value; }
		}

		/// <summary>
		/// 格式化索引
		/// </summary>
		/// <remarks>
		/// 输入 [{0}],索引显示为 [1] [2] [3] ... 输入 -{0}- ,显示为 -1- -2- -3- ...
		/// </remarks>
		[Browsable(true),
		DefaultValue(""),
		Category("导航文本"),
		Description("格式化索引。输入 [{0}],索引显示为 [1] [2] [3] ... 输入 -{0}- ,显示为 -1- -2- -3- ...")]
		public string FormatIndexString
		{
			get
			{
				object obj = ViewState["FormatIndexString"];
				return (obj == null) ? String.Empty : (string)obj;
			}
			set
			{
				ViewState["FormatIndexString"] = value;
			}
		}

		/// <summary>
		/// 显示跟多数据的文本，默认“...”
		/// </summary>
		[Browsable(true),
		Category("导航文本"),
		DefaultValue("..."),
		Description("显示跟多数据的文本，默认“...”")]
		public string MoreText
		{
			get
			{
				object obj = ViewState["MoreText"];
				return (obj == null) ? "..." : (string)obj;
			}
			set
			{
				ViewState["MoreText"] = value;
			}
		}

		/// <summary>
		/// 输入框前的文本
		/// </summary>
		[Browsable(true),
		Category("导航文本"),
		DefaultValue(""),
		Description("输入框前的文本")]
		public string TextBeforeInputBox
		{
			get
			{
				object obj = ViewState["TextBeforeInputBox"];
				return (obj == null) ? "" : (string)obj;
			}
			set
			{
				ViewState["TextBeforeInputBox"] = value;
			}
		}

		/// <summary>
		/// 输入框后的文本
		/// </summary>
		[Browsable(true),
		DefaultValue(""),
		Category("导航文本"),
		Description("输入框后的文本")]
		public string TextAfterInputBox
		{
			get
			{
				object obj = ViewState["TextAfterInputBox"];
				return (obj == null) ? "" : (string)obj;
			}
			set
			{
				ViewState["TextAfterInputBox"] = value;
			}
		}


		/// <summary>
		/// “ Go”按钮的文本
		/// </summary>
		[Browsable(true),
		Category("导航文本"),
		DefaultValue("跳转"),
		Description("“Go”按钮的文本")]
		public string SubmitButtonText
		{
			get
			{
				object obj = ViewState["SubmitButtonText"];
                return (obj == null) ? "跳转" : (string)obj;
			}
			set
			{
				if (value.Trim().Length > 0)
					ViewState["SubmitButtonText"] = value;
			}
		}

		/// <summary>
		/// 没有搜索结果时显示的文本
		/// </summary>
		[Browsable(true),
		Category("导航文本"),
		DefaultValue("对不起，没有找到您的搜索结果。"),
		Description("没有搜索结果时显示的文本")]
		public string NoResultsText
		{
			get
			{
				object obj = ViewState["NoResultsText"];
				return (obj == null) ? "对不起，没有找到您的搜索结果。" : (string)obj;
			}
			set
			{
				if (value.Trim().Length > 0)
					ViewState["NoResultsText"] = value;
			}
		}
		#endregion

		#region 导航样式
		/// <summary>
		/// 显示按钮的个数
		/// </summary>
		[Browsable(true),
		Description("显示按钮的个数"),
		Category("导航样式"),
		DefaultValue(5)]
		public int ButtonCount
		{
			get
			{
				object obj = ViewState["ButtonCount"];
				return (obj == null) ? 5 : (int)obj;
			}
			set
			{
				ViewState["ButtonCount"] = value;
			}
		}

		/// <summary>
		/// 页导航字段是否应显示“第一页”按钮
		/// </summary>
		[Browsable(true),
		Description("页导航字段是否应显示“第一页”按钮"),
		Category("导航样式"),
		DefaultValue(true)]
		public bool ShowFirstPageButton
		{
			get
			{
				object obj = ViewState["ShowFirstPageButton"];
				return (obj == null) ? true : (bool)obj;
			}
			set
			{
				ViewState["ShowFirstPageButton"] = value;
			}
		}

		/// <summary>
		/// 页导航字段是否应显示“上一页”按钮
		/// </summary>
		[Browsable(true),
		Description("页导航字段是否应显示“上一页”按钮"),
		Category("导航样式"),
		DefaultValue(true)]
		public bool ShowPreviousPageButton
		{
			get
			{
				object obj = ViewState["ShowPreviousPageButton"];
				return (obj == null) ? true : (bool)obj;
			}
			set
			{
				ViewState["ShowPreviousPageButton"] = value;
			}
		}

		/// <summary>
		/// 页导航字段是否应显示“下一页”按钮
		/// </summary>
		[Browsable(true),
		Description("页导航字段是否应显示“下一页”按钮"),
		Category("导航样式"),
		DefaultValue(true)]
		public bool ShowNextPageButton
		{
			get
			{
				object obj = ViewState["ShowNextPageButton"];
				return (obj == null) ? true : (bool)obj;
			}
			set
			{
				ViewState["ShowNextPageButton"] = value;
			}
		}

		/// <summary>
		/// 页导航字段是否应显示“最后一页”按钮
		/// </summary>
		[Browsable(true),
		Description("页导航字段是否应显示“最后一页”按钮"),
		Category("导航样式"),
		DefaultValue(true)]
		public bool ShowLastPageButton
		{
			get
			{
				object obj = ViewState["ShowLastPageButton"];
				return (obj == null) ? true : (bool)obj;
			}
			set
			{
				ViewState["ShowLastPageButton"] = value;
			}
		}

		/// <summary>
		/// 页导航字段是否应显示数字索引按钮
		/// </summary>
		[Browsable(true),
		Description("页导航字段是否应显示数字索引按钮"),
		Category("导航样式"),
		DefaultValue(false)]
		public bool ShowPageIndex
		{
			get
			{
				object obj = ViewState["ShowPageIndex"];
                return (obj == null) ? false : (bool)obj;
			}
			set
			{
				ViewState["ShowPageIndex"] = value;
			}
		}

		/// <summary>
		/// 页导航字段是否应显示输入框及按钮
		/// </summary>
		[Browsable(true),
		Description("页导航字段是否应显示输入框及按钮"),
		Category("导航样式"),
		DefaultValue(true)]
		public bool ShowInputBox
		{
			get
			{
				object obj = ViewState["ShowInputBox"];
				return (obj == null) ? true : (bool)obj;
			}
			set
			{
				ViewState["ShowInputBox"] = value;
			}
		}

		/// <summary>
		/// 页导航字段是应显示输入框及按钮时的总页数大小(包含)。例:ShowBoxThreshold = 10，PageCount >= 10时显示输入框及按钮。
		/// </summary>
		[Browsable(true),
		Description("页导航字段是应显示输入框及按钮时的总页数大小(包含)。例:ShowBoxThreshold = 10，PageCount >= 10时显示输入框及按钮。"),
		Category("导航样式"),
		DefaultValue(0)]
		public int ShowBoxThreshold
		{
			get
			{
				object obj = ViewState["ShowBoxThreshold"];
				return (obj == null) ? 0 : (int)obj;
			}
			set { ViewState["ShowBoxThreshold"] = value; }
		}

		/// <summary>
		/// 在第一页或最后一页时，是否显示对应的“第一页”、“前一页”、“后一页”、“最后一页”
		/// </summary>
		[Browsable(true),
		Description("在第一页或最后一页时，是否显示对应的“第一页”、“前一页”、“后一页”、“最后一页”"),
		Category("导航样式"),
		DefaultValue(true)]
		public bool ShowDisabledButtons
		{
			get
			{
				object obj = ViewState["ShowDisabledButtons"];
				return (obj == null) ? true : (bool)obj;
			}
			set
			{
				ViewState["ShowDisabledButtons"] = value;
			}
		}

		/// <summary>
		/// 设置按钮间间距
		/// </summary>
		[Browsable(true),
		Category("导航样式"),
		DefaultValue(typeof(Unit), "5px"),
		Description("设置按钮间间距")]
		public Unit PagingButtonSpacing
		{
			get
			{
				object obj = ViewState["PagingButtonSpacing"];
				return (obj == null) ? Unit.Pixel(5) : (Unit.Parse(obj.ToString()));
			}
			set
			{
				ViewState["PagingButtonSpacing"] = value;
			}
		}
		#endregion

		#region 错误提示
		/// <summary>
		/// 超出页面索引时的提示信息
		/// </summary>
		[Browsable(true),
		Description("超出页面索引时的提示信息"),
		DefaultValue("页数超出范围"),
		Category("错误提示")]
		public string PageIndexOutOfRangeErrorString
		{
			get
			{
				object obj = ViewState["PageIndexOutOfRangeErrorString"];
				return (obj == null) ? "页数超出范围" : (string)obj;
			}
			set
			{
				ViewState["PageIndexOutOfRangeErrorString"] = value;
			}
		}

		/// <summary>
		/// 页数输入错误时的提示信息
		/// </summary>
		[Browsable(true),
		Description("页数输入错误时的提示信息"),
		DefaultValue("页数输入错误"),
		Category("错误提示")]
		public string InvalidPageIndexErrorString
		{
			get
			{
				object obj = ViewState["InvalidPageIndexErrorString"];
				return (obj == null) ? "页数输入错误" : (string)obj;
			}
			set
			{
				ViewState["InvalidPageIndexErrorString"] = value;
			}
		}

		#endregion

		#region PageChanged Event
		/// <summary>
		/// 在当前页索引已更改时激发
		/// </summary>
		public event PageChangedEventHandler PageChanged;
		#endregion

		#region OnPageChanged Method
		/// <summary>
		/// 调用PageChanged
		/// </summary>
		/// <param name="e"> <see cref="PageChangedEventArgs"/> </param>
		protected virtual void OnPageChanged(PageChangedEventArgs e)
		{
			if (this.PageChanged != null)
				PageChanged(this, e);
		}

		#endregion

		#region PageChangedEventHandler Delegate
		/// <summary>
		/// 定义委托
		/// </summary>
		/// <param name="src">源</param>
		/// <param name="e">参数</param>
		public delegate void PageChangedEventHandler(object src, PageChangedEventArgs e);
		#endregion

		#region PageChangedEventArgs Class
		/// <summary>
		/// 翻页事件参数类
		/// </summary>
		public sealed class PageChangedEventArgs : EventArgs
		{
			private readonly int _newpageindex;

			/// <summary>
			/// 初始化
			/// </summary>
			/// <param name="newPageIndex">新索引</param>
			public PageChangedEventArgs(int newPageIndex)
			{
				this._newpageindex = newPageIndex;
			}

			public int NewPageIndex
			{
				get { return _newpageindex; }
			}
		}
		#endregion

		#region override控件呈现逻辑
		protected override void OnLoad(EventArgs e)
		{
			inputPageIndex = Page.Request.Form[this.UniqueID + "$txtIndex"];
			base.OnLoad(e);
		}

		protected override void OnPreRender(EventArgs e)
		{
			if (PageCount > 1)
			{
				if (ShowInputBox && PageCount >= ShowBoxThreshold)
				{
					string checkscript = "<script language=\"Javascript\">"
						+ "function doCheck(el)"
						+ "{"
							+ "var r=new RegExp(\"^\\\\s*(\\\\d+)\\\\s*$\");"
							+ "if(r.test(el.val()))"
							+ "{"
								+ "if(RegExp.$1<1||RegExp.$1>" + PageCount.ToString() + ")"
								+ "{"
									+ "alert(\"" + PageIndexOutOfRangeErrorString + "\");"
									+ "$(\'#" + this.ClientID + "_txtIndex\').first().select();"
									+ "return false;"
								+ "}"
								+ "return true;"
							+ "}"
							+ "alert(\"" + InvalidPageIndexErrorString + "\");"
							+ "$(\'#" + this.ClientID + "_txtIndex\').first().select();"
							+ "return false;"
						+ "}"
						+ "</script>";
					Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "checkinput", checkscript, false);
				}
			}
			base.OnPreRender(e);
		}

		protected override void AddAttributesToRender(HtmlTextWriter writer)
		{
			if (this.Page != null)
				this.Page.VerifyRenderingInServerForm(this);
			base.AddAttributesToRender(writer);
		}

		public override void RenderBeginTag(HtmlTextWriter writer)
		{
			if (!String.IsNullOrEmpty(CssClass))
				writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
			base.RenderBeginTag(writer);
			//页数大于1时显示控件
			if (PageCount > 1)
			{
				writer.AddAttribute(HtmlTextWriterAttribute.Width, "100%");
				writer.AddAttribute(HtmlTextWriterAttribute.Style, GetStyleString());
				//if (Height != Unit.Empty)
				//    writer.AddStyleAttribute(HtmlTextWriterStyle.Height, Height.ToString());
				writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
				writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
				writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");

				writer.RenderBeginTag(HtmlTextWriterTag.Table);
				writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");
				writer.RenderBeginTag(HtmlTextWriterTag.Tr);
				WriteCellAttributes(writer, true);
				writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0");
				writer.RenderBeginTag(HtmlTextWriterTag.Td);
			}
		}

		public override void RenderEndTag(HtmlTextWriter writer)
		{
			//页数大于1时显示控件
			if (PageCount > 1)
			{
				writer.RenderEndTag();
				writer.RenderEndTag();
				writer.RenderEndTag();
			}
			base.RenderEndTag(writer);
			writer.WriteLine();
		}

		protected override void RenderContents(HtmlTextWriter writer)
		{
			if (RecordCount == 0)
			{
				writer.Write("<div style='text-align: center; width: 100%;'><font style=" + "\"font-size:12px\"" + " >" + NoResultsText + "</font></div>");
				return;
			}
			//只有一页时不显示控件
			if (PageCount <= 1)
				return;


			this.CreateNavigationButton(writer, "btnfirst");
			writer.Write("&nbsp;&nbsp;");
			this.CreateNavigationButton(writer, "btnprev");
			writer.Write("&nbsp;&nbsp;");
			if (ShowPageIndex)
			{
			    int Startpage, Endpage;
			    if (ButtonCount % 2 == 1)
			    {
				    Startpage = PageIndex - (ButtonCount - 1) / 2;
				    Endpage = PageIndex + (ButtonCount - 1) / 2;
			    }
			    else
			    {
				    Startpage = PageIndex - (ButtonCount / 2 - 1);
				    Endpage = PageIndex + ButtonCount / 2;
			    }
			    if (Startpage < 1)
			    {
				    Endpage = Endpage + 1 - Startpage > PageCount ? PageCount : Endpage + 1 - Startpage;
				    Startpage = 1;
			    }
			    if (Endpage > PageCount)
			    {
				    Startpage = Startpage - (Endpage - PageCount) < 0 ? 1 : Startpage - (Endpage - PageCount);
				    Endpage = PageCount;
			    }

				if (Startpage > 1)
				{
					CreateMoreButton(writer, Startpage);
					writer.Write("&nbsp;");
				}
				for (int i = Startpage; i <= Endpage; i++)
				{
					CreateNumericButton(writer, i);
					writer.Write("&nbsp;");
				}
				if (Endpage < PageCount)
				{
					CreateMoreButton(writer, Endpage + 1);
					writer.Write("&nbsp;");
				}
			}
			this.CreateNavigationButton(writer, "btnnext");
			writer.Write("&nbsp;&nbsp;");
			this.CreateNavigationButton(writer, "btnlast");
			writer.Write("&nbsp;&nbsp;");
            writer.Write(PageIndex + "/" + PageCount + "页");

			if (ShowInputBox && PageCount >= ShowBoxThreshold)
			{
				writer.Write("&nbsp;&nbsp;&nbsp;&nbsp;");
				if (TextBeforeInputBox != null)
					writer.Write(TextBeforeInputBox);
				writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
				writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "30px");
				writer.AddAttribute(HtmlTextWriterAttribute.Value, PageIndex.ToString());
				writer.AddAttribute(HtmlTextWriterAttribute.Class, "BNPagerTextbox");
				//if (InputBoxStyle != null && InputBoxStyle.Trim().Length > 0)
				//    writer.AddAttribute(HtmlTextWriterAttribute.Style, InputBoxStyle);
				//if (InputBoxClass != null && InputBoxClass.Trim().Length > 0)
				//    writer.AddAttribute(HtmlTextWriterAttribute.Class, InputBoxClass);
				if (PageCount <= 1)
					writer.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "true");
				writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_txtIndex");
				writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID + "$txtIndex");
				string scriptRef = "doCheck($(\'#" + this.ClientID + "_txtIndex\').first())";
				string postRef = "if(event.keyCode==13)"
+ "{"
	+ "/*"
	+ "if(" + scriptRef + ")"
	+ "{*/"
		+ "__doPostBack(\'" + this.UniqueID + "\',$(\'#" + this.ClientID + "_txtIndex\').first().val());"
	+ "/*}"
	+ "else"
	+ "{"
		+ "event.returnValue=false;"
		+ "return false;"
	+ "}"
	+ "*/"
+ "}";
				writer.AddAttribute("onkeydown", postRef);
				writer.RenderBeginTag(HtmlTextWriterTag.Input);
				writer.RenderEndTag();
				if (TextAfterInputBox != null)
					writer.Write(TextAfterInputBox);
				writer.Write("&nbsp;&nbsp;");
				writer.AddAttribute(HtmlTextWriterAttribute.Type, "Submit");
				writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID + "$btnGo");
				writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_btnGo");
				writer.AddAttribute(HtmlTextWriterAttribute.Value, SubmitButtonText);
				writer.AddAttribute(HtmlTextWriterAttribute.Class, "BNPagerButtonGo");
				//if (SubmitButtonClass != null && SubmitButtonClass.Trim().Length > 0)
				//    writer.AddAttribute(HtmlTextWriterAttribute.Class, SubmitButtonClass);
				//if (SubmitButtonStyle != null && SubmitButtonStyle.Trim().Length > 0)
				//    writer.AddAttribute(HtmlTextWriterAttribute.Style, SubmitButtonStyle);
				if (PageCount <= 1)
				{
					writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "true");
					writer.AddAttribute(HtmlTextWriterAttribute.Style, "color:silver");
				}
				writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "__doPostBack(\'" + this.UniqueID + "\',$(\'#" + this.ClientID + "_txtIndex\').first().val());"/* + scriptRef*/);
				writer.RenderBeginTag(HtmlTextWriterTag.Input);
				writer.RenderEndTag();
			}
		}
		#endregion

		#region 内部方法
		/// <summary>
		/// 获取Style字符串
		/// </summary>
		/// <returns></returns>
		private string GetStyleString()
		{
			if (Style.Count > 0)
			{
				string stl = null;
				string[] skeys = new string[Style.Count];
				Style.Keys.CopyTo(skeys, 0);
				for (int i = 0; i < skeys.Length; i++)
				{
					stl += String.Concat(skeys[i], ":", Style[skeys[i]], ";");
				}
				return stl += "vertical-align:middle;";
			}
			return null;
		}

		/// <summary>
		/// 为导航和用户区域的td设置Attribute
		/// </summary>
		/// <param name="writer"><see cref="System.Web.UI.HtmlTextWriter"/</param>
		/// <param name="leftCell">是否是第一个td</param>
		private void WriteCellAttributes(HtmlTextWriter writer, bool leftCell)
		{
			//用户区40%的宽度
			string customUnit = "40%";
			if (leftCell)
			{
				writer.AddAttribute(HtmlTextWriterAttribute.Class, "BNPagerTd");
				writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, "right");
				//if (CustomInfoStyle != null && CustomInfoStyle.Trim().Length > 0)
				//    writer.AddAttribute(HtmlTextWriterAttribute.Style, CustomInfoStyle);
				writer.AddAttribute(HtmlTextWriterAttribute.Valign, "middle");
				writer.AddStyleAttribute(HtmlTextWriterStyle.Width, customUnit);
				writer.AddAttribute(HtmlTextWriterAttribute.Align, HorizontalAlign.Right.ToString().ToLower());
			}
			else
			{
				customUnit = (Unit.Percentage(100 - 40)).ToString();
				writer.AddAttribute(HtmlTextWriterAttribute.Class, "BNPagerTd");
                writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, "right");
				//if (CustomInfoStyle != null && CustomInfoStyle.Trim().Length > 0)
				//    writer.AddAttribute(HtmlTextWriterAttribute.Style, CustomInfoStyle);
				writer.AddStyleAttribute(HtmlTextWriterStyle.Width, customUnit);
				writer.AddAttribute(HtmlTextWriterAttribute.Valign, "middle");
				writer.AddAttribute(HtmlTextWriterAttribute.Align, HorizontalAlign.ToString().ToLower());
			}
			writer.AddAttribute(HtmlTextWriterAttribute.Nowrap, "true");
		}

		/// <summary>
		/// 获取带有超链接的导航按钮的字符串
		/// </summary>
		/// <param name="pageIndex">导航按钮的索引值</param>
		/// <returns>链接字符串</returns>
		private string GetHrefString(int pageIndex)
		{
			return Page.ClientScript.GetPostBackClientHyperlink(this, pageIndex.ToString());
		}

		/// <summary>
		/// 创建导航按钮
		/// </summary>
		/// <param name="writer"><see cref="System.Web.UI.HtmlTextWriter"/></param>
		/// <param name="btnname">button name</param>
		private void CreateNavigationButton(HtmlTextWriter writer, string btnname)
		{

			if (!ShowFirstPageButton && btnname == "btnfirst")
				return;
			if (!ShowPreviousPageButton && btnname == "btnprev")
				return;
			if (!ShowNextPageButton && btnname == "btnnext")
				return;
			if (!ShowLastPageButton && btnname == "btnlast")
				return;

			int pageIndex;
			string linktext = String.Empty;
			bool disabled;

			switch (btnname)
			{
				case "btnfirst":
					pageIndex = 1;
					linktext = FirstPageText;
					disabled = (PageIndex <= 1);
					break;
				case "btnprev":
					pageIndex = (PageIndex == 1 ? 1 : (PageIndex - 1));
					linktext = PreviousPageText;
					disabled = (PageIndex <= 1);
					break;
				case "btnnext":
					pageIndex = (PageIndex == PageCount ? PageCount : (PageIndex + 1));
					linktext = NextPageText;
					disabled = (PageIndex >= PageCount);
					break;
				case "btnlast":
					pageIndex = PageCount;
					linktext = LastPageText;
					disabled = (PageIndex >= PageCount);
					break;
				default:
					pageIndex = 1;
					linktext = "错误";
					disabled = true;
					break;
			}
			if (!ShowDisabledButtons && disabled)
				return;

			string strBtnPageName = String.Concat(this.UniqueID, "$", btnname);
			string strBtnPageId = String.Concat(this.ClientID, "_", btnname);
			string strBtnPageScript;

			if (disabled)
			{
				writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "true");
				writer.AddAttribute(HtmlTextWriterAttribute.Style, "color:silver");
			}
			strBtnPageScript = Page.ClientScript.GetPostBackEventReference(this, pageIndex.ToString());
			//显示为button
			//writer.AddAttribute(HtmlTextWriterAttribute.Type, "Button");//Submit
			//writer.AddAttribute(HtmlTextWriterAttribute.Name, strBtnPageName);
			//writer.AddAttribute(HtmlTextWriterAttribute.Id, strBtnPageId);
			//writer.AddAttribute(HtmlTextWriterAttribute.Class, "BNPagerButton");
			//writer.AddAttribute(HtmlTextWriterAttribute.Value, linktext);
			//writer.AddAttribute(HtmlTextWriterAttribute.Onclick, strBtnPageScript);
			//writer.RenderBeginTag(HtmlTextWriterTag.Input);
			//writer.RenderEndTag();

			//显示为link
			writer.AddAttribute(HtmlTextWriterAttribute.Href, GetHrefString(pageIndex));
			writer.AddAttribute(HtmlTextWriterAttribute.Name, strBtnPageName);
			writer.AddAttribute(HtmlTextWriterAttribute.Id, strBtnPageId);
			writer.AddAttribute(HtmlTextWriterAttribute.Class, "BNPagerLink");			
			writer.AddAttribute(HtmlTextWriterAttribute.Onclick, strBtnPageScript);
			writer.AddAttribute(HtmlTextWriterAttribute.Style, "text-decoration:none;");
            
			writer.RenderBeginTag(HtmlTextWriterTag.A);
			writer.Write(linktext);
			writer.RenderEndTag();

			WriteButtonSpace(writer);
		}

		/// <summary>
		/// 创建数字索引按钮
		/// </summary>
		/// <param name="writer"><see cref="System.Web.UI.HtmlTextWriter"/></param>
		/// <param name="index">页面索引</param>
		private void CreateNumericButton(HtmlTextWriter writer, int index)
		{
			bool isCurrent = (index == PageIndex);
			if (isCurrent)
			{
				writer.AddStyleAttribute(HtmlTextWriterStyle.FontWeight, "Bold");
				writer.AddStyleAttribute(HtmlTextWriterStyle.Color, "red");
				writer.RenderBeginTag(HtmlTextWriterTag.Font);
				if (FormatIndexString.Length > 0)
					writer.Write(String.Format(FormatIndexString, (index.ToString())));
				else
					writer.Write(index.ToString());
				writer.RenderEndTag();
			}
			else
			{
				writer.AddAttribute(HtmlTextWriterAttribute.Href, GetHrefString(index));
				writer.AddAttribute(HtmlTextWriterAttribute.Class, "BNPagerIndexLink");
				writer.RenderBeginTag(HtmlTextWriterTag.A);
				if (FormatIndexString.Length > 0)
					writer.Write(String.Format(FormatIndexString, (index.ToString())));
				else
					writer.Write(index.ToString());
				writer.RenderEndTag();
			}
			WriteButtonSpace(writer);
		}

		/// <summary>
		/// 添加间距
		/// </summary>
		/// <param name="writer"></param>
		private void WriteButtonSpace(HtmlTextWriter writer)
		{
			if (PagingButtonSpacing.Value > 0)
			{
				writer.AddStyleAttribute(HtmlTextWriterStyle.Width, PagingButtonSpacing.ToString());
				writer.RenderBeginTag(HtmlTextWriterTag.Span);
				writer.RenderEndTag();
			}
		}

		/// <summary>
		/// 创建 more(...) 按钮
		/// </summary>
		/// <param name="writer"><see cref="System.Web.UI.HtmlTextWriter"/></param>
		/// <param name="pageIndex">页面索引</param>
		private void CreateMoreButton(HtmlTextWriter writer, int pageIndex)
		{
			writer.RenderBeginTag(HtmlTextWriterTag.Span);
			writer.Write(MoreText);
			writer.RenderEndTag();
		}
		#endregion

		#region IPostBackEventHandler 成员

		public void RaisePostBackEvent(string eventArgument)
		{
			int pageIndex = PageIndex;
			try
			{
				if (eventArgument == null || eventArgument == String.Empty)
					eventArgument = inputPageIndex;

				pageIndex = int.Parse(eventArgument);
			}
			catch { }
			OnPageChanged(new PageChangedEventArgs(pageIndex));
		}

		#endregion

		#region IPostBackDataHandler 成员

		public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
		{
			string str = postCollection[this.UniqueID + "$txtIndex"];
			if (str != null && str.Trim().Length > 0)
			{
				try
				{
					int pindex = int.Parse(str);
					if (pindex > 0 && pindex <= PageCount)
					{
						inputPageIndex = str;
						Page.RegisterRequiresRaiseEvent(this);
					}
				}
				catch
				{ }
			}
			return false;
		}

		public void RaisePostDataChangedEvent()
		{
			
		}

		#endregion
	}

	#region BNPager Control Designer
	/// <summary>
	/// <see cref="BNPager"/> 设计器
	/// </summary>
	public class PagerDesigner : System.Web.UI.Design.ControlDesigner
	{
		public PagerDesigner()
		{

		}
		private BNPager gp;

		public override string GetDesignTimeHtml()
		{
			this.gp = (BNPager)base.Component;
			this.gp.RecordCount = 0xe1;
			StringWriter writer1 = new StringWriter();
			HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
			this.gp.RenderControl(writer2);
			return writer1.ToString();
		}

		public override string GetEditableDesignerRegionContent(System.Web.UI.Design.EditableDesignerRegion region)
		{
			region.Selectable = false;
			return null;
		}

		protected override string GetErrorDesignTimeHtml(Exception e)
		{
			string errorstr = "Errors while creating control:" + e.Message;
			return base.CreatePlaceHolderDesignTimeHtml(errorstr);
		}
	}
	#endregion
}

